package com.chuangjian.hire.users.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chuangjian.hire.common.dto.LabelValueDTO;
import com.chuangjian.hire.common.exceptionEnum.ApiExceptionEnum;
import com.chuangjian.hire.common.exption.ApiException;
import com.chuangjian.hire.product.dto.ProductUserDTO;
import com.chuangjian.hire.sms.enums.SmsTypeEnums;
import com.chuangjian.hire.sms.service.SmsCodeService;
import com.chuangjian.hire.users.dao.RoleMapper;
import com.chuangjian.hire.users.dao.UsersMapper;
import com.chuangjian.hire.users.dao.UsersRoleMapper;
import com.chuangjian.hire.users.domain.MenuDO;
import com.chuangjian.hire.users.domain.RoleDO;
import com.chuangjian.hire.users.domain.UsersDO;
import com.chuangjian.hire.users.domain.UsersRoleDO;
import com.chuangjian.hire.users.dto.*;
import com.chuangjian.hire.users.enums.TypeEnum;
import com.chuangjian.hire.users.enums.ValidEnum;
import com.chuangjian.hire.users.service.UsersService;
import com.chuangjian.hire.util.BeanUtils;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * FileName: UsersBusiness
 * Description:
 *
 * @author: CodeGenerator
 * @date: 2020/07/09 19:08
 * Copyright (C) 杭州同基汽车科技有限公司
 */
@Transactional
@Service("usersService")
public class UsersServiceImpl extends ServiceImpl<UsersMapper, UsersDO> implements UsersService {

    @Resource
    SmsCodeService smsCodeService;
    @Resource
    SSOCacheImpl ssoCache;


    @Resource
    UsersRoleMapper usersRoleMapper;
    @Resource
    RoleMapper roleMapper;


    @Override
    public UsersDO findById(Long userID) {
        return getById(userID);
    }

    @Override
    public Boolean register(RegisterDTO register) {
        boolean isOk = smsCodeService.verifySmsCode(register.getPhone(), register.getMsgCode(), SmsTypeEnums.REGISTER.getValue());
        if (!isOk) {
            throw new ApiException(ApiExceptionEnum.MOBILE_CODE_ERROR);
        }
        if (TypeEnum.getType(register.getType()) == null) {
            throw new ApiException(ApiExceptionEnum.USER_TYPE_ERROR);
        }
        UsersDO phone = getByPhone(register.getPhone());
        if (phone != null) {
            throw new ApiException(ApiExceptionEnum.MOBILE_ERROR);
        }

        UsersDO user = new UsersDO();
//        user.setType(register.getType());
        user.setPhone(register.getPhone());
//        user.setNickName(register.getPhone().substring(7));
        user.setLoginPwd(register.getPassword());
//        user.setPayPwd(register.getPassword());
        save(user);

        return true;
    }

    @Override
    public UserDTO login(LoginDTO login) {
        UsersDO users = getByPhone(login.getPhone());
        if (users == null || !ValidEnum.valid.getValue().equals(users.getStatus())) {
            throw new ApiException(ApiExceptionEnum.USER_NOT_EXIST);
        }
        if (!Objects.equals(login.getPassword(), users.getLoginPwd())) {
            throw new ApiException(ApiExceptionEnum.USER_NOT_EXIST);
        }
        UserDTO userDTO = toDTO(users);

        setMenu(userDTO);

        return userDTO;
    }

    @Override
    public UserDTO getUserById(Long userId) {

        UserDTO userDTO = toDTO(getById(userId));

        setMenu(userDTO);

        return userDTO;
    }


    @Override
    public UserPayDTO getUserPayInfoById(Long userId) {
        return BeanUtil.toBean(getById(userId), UserPayDTO.class);
    }

    private UserDTO toDTO(UsersDO users) {
        return BeanUtil.toBean(users, UserDTO.class);
    }

    private UserDTO setMenu(UserDTO user) {
        List<MenuDO> menuDTOS = baseMapper.selectMenList(user.getId());
        user.setMenus(treeify(menuDTOS));
        return user;
    }


    public static List<MenuDTO> treeify(List<MenuDO> menuList) {

        Map<Long, List<MenuDTO>> level4GroupByPid = menuList.stream()
                .filter(it -> it.getLevel() == 4)
                .filter(it -> it.getPId() != null)
                .map(it -> BeanUtils.transform(MenuDTO.class, it))
                .collect(Collectors.groupingBy(MenuDO::getPId));

        Map<Long, List<MenuDTO>> level3GroupByPid = menuList.stream()
                .filter(it -> it.getLevel() == 3)
                .filter(it -> it.getPId() != null)
                .map(it -> BeanUtils.transform(MenuDTO.class, it))
                .map(it -> {
                    it.setChildren(level4GroupByPid.get(it.getId()));
                    return it;
                })
                .collect(Collectors.groupingBy(MenuDO::getPId));

        Map<Long, List<MenuDTO>> level2GroupByPId = menuList.stream()
                .filter(it -> it.getLevel() == 2)
                .filter(it -> it.getPId() != null)
                .map(it -> BeanUtils.transform(MenuDTO.class, it))
                .map(it -> {
                    it.setChildren(level3GroupByPid.get(it.getId()));
                    return it;
                })
                .collect(Collectors.groupingBy(MenuDO::getPId));

        List<MenuDTO> level1 = menuList.stream().filter(it -> it.getLevel() == 1).map(it -> BeanUtils.transform(MenuDTO.class, it)).map(it -> {
            it.setChildren(level2GroupByPId.get(it.getId()));
            return it;
        }).collect(Collectors.toList());
        return level1;
    }


    private Integer getSecurityLevel(UsersDO users) {
//        String payPwd = users.getPayPwd();
        String email = users.getEmail();
        Integer level = 1;
        if (StringUtils.isNotBlank(email)) {
            level = +1;
        }
//        if (StringUtils.isNotBlank(payPwd)) {
//            level = +1;
//        }
        return level;
    }

    @Override
    public Boolean forget(ForgetDTO forget) {
        boolean isOK = smsCodeService.verifySmsCode(forget.getPhone(), forget.getMsgCode(), SmsTypeEnums.FORGET_CODE.getValue());
        if (!isOK) {
            throw new ApiException(ApiExceptionEnum.MOBILE_CODE_ERROR);
        }
        UsersDO users = getByPhone(forget.getPhone());
        if (users == null) {
            throw new ApiException(ApiExceptionEnum.USER_NOT_EXIST);
        }
        users.setLoginPwd(forget.getPassword());

        updateById(users);
        return ssoCache.refreshCache(toDTO(users));
    }

    @Override
    public Boolean changePhone(ForgetDTO forget, UserDTO userInfo) {
        boolean isOK = smsCodeService.verifySmsCode(forget.getPhone(), forget.getMsgCode(), SmsTypeEnums.CHANGE_PHONE.getValue());
        if (!isOK) {
            throw new ApiException(ApiExceptionEnum.MOBILE_CODE_ERROR);
        }
        UsersDO userDO = getById(userInfo.getId());
        userDO.setPhone(forget.getPhone());
        updateById(userDO);
        return ssoCache.refreshCache(toDTO(userDO));
    }

    @Override
    public Boolean changeLoginPassword(PasswordDTO password, UserDTO userInfo) {

        UsersDO users = getById(userInfo.getId());

        if (!Objects.equals(users.getLoginPwd(), password.getOldPassword())) {
            throw new ApiException(ApiExceptionEnum.PASSWORD_ERROR);
        }
        users.setLoginPwd(password.getPassword());

        updateById(users);
        return ssoCache.refreshCache(toDTO(users));
    }

    @Override
    public Boolean changePayPassword(PasswordDTO password, UserDTO userInfo) {
        Long id = userInfo.getId();
        UsersDO byId = getById(id);

//        if (!Objects.equals(byId.getPayPwd(), password.getOldPassword())) {
//            throw new ApiException(ApiExceptionEnum.PASSWORD_ERROR);
//        }
//        byId.setPayPwd(password.getPassword());
        updateById(byId);
        return ssoCache.refreshCache(toDTO(byId));
    }

    @Override
    public Boolean bindPayPassword(BindPasswordDTO password, UserDTO userInfo) {
        boolean isOK = smsCodeService.verifySmsCode(userInfo.getPhone(), password.getMsgCode(), SmsTypeEnums.SMS_CODE.getValue());
        if (!isOK) {
            throw new ApiException(ApiExceptionEnum.MOBILE_CODE_ERROR);
        }
        UsersDO byId = getById(userInfo.getId());
//        byId.setPayPwd(password.getPassword());
        updateById(byId);
        return ssoCache.refreshCache(toDTO(byId));
    }

    @Override
    public Boolean bindAliPay(BindAliPayDTO aliPay, UserDTO userInfo) {
        boolean isOk = smsCodeService.verifySmsCode(userInfo.getPhone(), aliPay.getMsgCode(), SmsTypeEnums.BIND_ALI_PAY.getValue());
        if (!isOk) {
            throw new ApiException(ApiExceptionEnum.MOBILE_CODE_ERROR);
        }
        UsersDO byId = getById(userInfo.getId());
//        byId.setAliPayAccount(aliPay.getAliPayAccount());
//        byId.setAliPayName(aliPay.getAliPayName());
        updateById(byId);
        return ssoCache.refreshCache(toDTO(byId));
    }

    @Override
    public Boolean bindEmail(EmailDTO emailDTO) {
        UsersDO byId = getById(emailDTO.getUserId());
        byId.setEmail(emailDTO.getEmail());
        updateById(byId);
        return ssoCache.refreshCache(toDTO(byId));
    }

    @Override
    public Boolean uploadIcon(String icon, UserDTO userInfo) {
        UsersDO byId = getById(userInfo.getId());
//        byId.setIcon(icon);
        updateById(byId);
        return ssoCache.refreshCache(toDTO(byId));
    }

    @Override
    public Integer getWorkStatus(Long userId) {
//        return getById(userId).getWorkStatus();
        return 0;
    }

    @Override
    public Boolean changeWorkStatus(Integer workStatus, UserDTO userInfo) {
        UsersDO byId = getById(userInfo.getId());
//        byId.setWorkStatus(workStatus);
        updateById(byId);
        return ssoCache.refreshCache(toDTO(byId));
    }

    @Override
    public SalaryDTO getSalary(Long userId) {
        return BeanUtil.toBean(getById(userId), SalaryDTO.class);
    }

    @Override
    public Boolean editSalary(Long userId, SalaryDTO salary) {
//        update(Wrappers.<UsersDO>lambdaUpdate()
//                .set(salary.getPayMonth() != null, UsersDO::getPayMonth, salary.getPayMonth())
//                .set(salary.getPayCustom() != null, UsersDO::getPayCustom, salary.getPayCustom())
//                .eq(UsersDO::getId, userId));

        UsersDO users = getById(userId);
        return ssoCache.refreshCache(toDTO(users));
    }

    @Override
    public OrgDTO getOrgInfo(Long userId) {
        return BeanUtils.transform(OrgDTO.class, getById(userId));
    }

    @Override
    public Boolean editOrgInfo(OrgDTO editInfo, UserDTO userInfo) {

//        update(Wrappers.<UsersDO>lambdaUpdate()
//                .set(UsersDO::getOrgName, editInfo.getOrgName())
//                .set(UsersDO::getOrgType, editInfo.getOrgType())
//                .set(UsersDO::getOrgTypeId, editInfo.getOrgTypeId())
//                .set(UsersDO::getOrgLabel, editInfo.getOrgLabel())
//                .set(UsersDO::getOrgIntro, editInfo.getOrgIntro())
//                .set(UsersDO::getOrgProvince, editInfo.getOrgProvince())
//                .set(UsersDO::getOrgProvinceId, editInfo.getOrgProvinceId())
//                .set(UsersDO::getOrgCity, editInfo.getOrgCity())
//                .set(UsersDO::getOrgCityId, editInfo.getOrgCityId())
//                .set(UsersDO::getOrgDistrict, editInfo.getOrgDistrict())
//                .set(UsersDO::getOrgDistrictId, editInfo.getOrgDistrictId())
//                .set(UsersDO::getOrgDetailAddress, editInfo.getOrgDetailAddress())
//                .eq(UsersDO::getId, userInfo.getId()));
        return true;
    }

    @Override
    public EditInfoDTO getEditInfo(Long userId) {
        return BeanUtil.toBean(getById(userId), EditInfoDTO.class);
    }

    @Override
    public Boolean editInfo(EditInfoDTO editInfo, UserDTO userInfo) {
//        update(Wrappers.<UsersDO>lambdaUpdate()
//                .set(UsersDO::getIcon, editInfo.getIcon())
//                .set(UsersDO::getNickName, editInfo.getNickName())
//                .set(UsersDO::getRealName, editInfo.getRealName())
//                .set(UsersDO::getNation, editInfo.getNation())
//                .set(UsersDO::getAge, editInfo.getAge())
//                .set(UsersDO::getSex, editInfo.getSex())
//                .set(UsersDO::getEducation, editInfo.getEducation())
//                .set(UsersDO::getWorkAge, editInfo.getWorkAge())
//                .set(UsersDO::getGraduate, editInfo.getGraduate())
//                .set(UsersDO::getProvince, editInfo.getProvince())
//                .set(UsersDO::getProvinceId, editInfo.getProvinceId())
//                .set(UsersDO::getCity, editInfo.getCity())
//                .set(UsersDO::getCityId, editInfo.getCityId())
//                .set(UsersDO::getDistrict, editInfo.getDistrict())
//                .set(UsersDO::getDistrictId, editInfo.getDistrictId())
//                .set(UsersDO::getDetailAddress, editInfo.getDetailAddress())
//                .eq(UsersDO::getId, userInfo.getId()));

        UsersDO users = getById(userInfo.getId());
        return ssoCache.refreshCache(toDTO(users));
    }

    @Override
    public ContactDTO getContact(Long userId) {
        return BeanUtil.toBean(getById(userId), ContactDTO.class);
    }

    @Override
    public Boolean editContact(ContactDTO contact, UserDTO userInfo) {
        update(Wrappers.<UsersDO>lambdaUpdate()
//                .set(UsersDO::getQq, contact.getQq())
//                .set(UsersDO::getWechat, contact.getWechat())
                .eq(UsersDO::getId, userInfo.getId()));
        UsersDO users = getById(userInfo.getId());
        return ssoCache.refreshCache(toDTO(users));
    }

    @Override
    public IntroDTO getIntro(Long userId) {
        return BeanUtil.toBean(getById(userId), IntroDTO.class);
    }

    @Override
    public Boolean editIntro(Long userId, IntroDTO intro) {
        update(Wrappers.<UsersDO>lambdaUpdate()
//                .set(StringUtils.isNotBlank(intro.getIntro()), UsersDO::getIntro, intro.getIntro())
//                .set(StringUtils.isNotBlank(intro.getResumeUrl()), UsersDO::getResumeUrl, intro.getResumeUrl())
                .eq(UsersDO::getId, userId));
        UsersDO users = getById(userId);
        return ssoCache.refreshCache(toDTO(users));
    }

    @Override
    public Boolean reduceBalance(BigDecimal amount, Long userId) {
//        BigDecimal balance = getById(userId).getBalance();
//        if (balance == null) {
//            balance = new BigDecimal(0);
//        }
//        balance = balance.subtract(amount);
//
//        if (balance.compareTo(BigDecimal.ZERO) < 0) {
//            throw new ApiException(ApiExceptionEnum.BALANCE_ERROR);
//        }
//        update(Wrappers.<UsersDO>lambdaUpdate()
//                .set(UsersDO::getBalance, balance)
//                .eq(UsersDO::getId, userId));

        UsersDO users = getById(userId);
        return ssoCache.refreshCache(toDTO(users));
    }

    @Override
    public Boolean reduceFreezeBalance(BigDecimal amount, Long userId) {
        UsersDO users = getById(userId);
//        BigDecimal freezeBalance = users.getFreezeBalance();
//        if (freezeBalance == null) {
//            freezeBalance = new BigDecimal(0);
//        }
//        freezeBalance = freezeBalance.subtract(amount);
//
//        if (freezeBalance.compareTo(BigDecimal.ZERO) < 0) {
//            throw new ApiException(ApiExceptionEnum.BALANCE_ERROR);
//        }
//        update(Wrappers.<UsersDO>lambdaUpdate()
//                .set(UsersDO::getFreezeBalance, freezeBalance)
//                .eq(UsersDO::getId, userId));
        return ssoCache.refreshCache(toDTO(users));
    }

    @Override
    public Boolean addBalance(BigDecimal amount, Long userId) {
        UsersDO users = getById(userId);
//        BigDecimal balance = users.getBalance();
//        if (balance == null) {
//            balance = new BigDecimal(0);
//        }
//        balance = balance.add(amount);
//        update(Wrappers.<UsersDO>lambdaUpdate()
//                .set(UsersDO::getBalance, balance)
//                .eq(UsersDO::getId, userId));
        return ssoCache.refreshCache(toDTO(users));
    }

    @Override
    public Boolean addFreezeBalance(BigDecimal amount, Long userId) {
        UsersDO users = getById(userId);
//        BigDecimal freezeBalance = users.getFreezeBalance();
//        if (freezeBalance == null) {
//            freezeBalance = new BigDecimal(0);
//        }
//        freezeBalance = freezeBalance.add(amount);
//        update(Wrappers.<UsersDO>lambdaUpdate()
//                .set(UsersDO::getFreezeBalance, freezeBalance)
//                .eq(UsersDO::getId, userId));
        return ssoCache.refreshCache(toDTO(users));
    }

    @Override
    public Boolean confirmPayPwd(Long userId, String payPwd) {
//        UsersDO users = getById(userId);
//        return Objects.equals(payPwd, users.getPayPwd());
        return true;
    }

    @Override
    public ProductUserDTO getProductUserById(Long userId) {
        return BeanUtils.transform(ProductUserDTO.class, getById(userId));
    }

    @Override
    public List<ProductUserDTO> getUserByIds(List<Long> userIdList) {
        if (CollectionUtil.isEmpty(userIdList)) {
            return Collections.emptyList();
        }
        List<UsersDO> usersDOS = listByIds(userIdList);
        return BeanUtils.transformList(ProductUserDTO.class, usersDOS);
    }

    @Override
    public UsersDTO getUserDetailById(Long userId) {
        List<Long> userIds = Arrays.asList(userId);
        UsersDO usersDO = getById(userId);
        if (usersDO == null) {
            return null;
        }
//        Map<Long, List<ProductDTO>> productList = usersProductService.getProductList(userIds);
        UsersDTO users = BeanUtils.transform(UsersDTO.class, usersDO);
//        Integer education = users.getEducation();
//        users.setEducations(EducationEnum.getLabels(education));
//        users.setProductList(productList.get(userId));
//        users.setUsersCatalogList(userCatalogService.getUserCatalogList(usersDO.getCatalogIdList()));
//        users.setUsersLabelList(StringUtil.getList(usersDO.getLabelList()));
        return users;
    }

    @Override
    public Page<UsersDTO> searchUsers(Page page, SearchUsersDTO search) {

        Wrapper query = Wrappers.<UsersDO>lambdaQuery();
//                .eq(UsersDO::getType, TypeEnum.DESIGNER.getValue())
//                .and(StringUtils.isNotBlank(search.getContent()), it -> it.like(UsersDO::getNickName, search.getContent()).or().like(UsersDO::getLabelList, search.getContent()))
//                .in(search.getCatalogId() != null, UsersDO::getCatalogIdList, search.getCatalogId())
//                .eq(search.getLevel() != null, UsersDO::getWorkAge, search.getLevel())
//                .eq(search.getSex() != null, UsersDO::getSex, search.getSex())
//                .orderByDesc(UsersDO::getRecommendSort, UsersDO::getFreshSort);
        Page<UsersDO> pageResult = page(page, query);
        List<UsersDO> records = pageResult.getRecords();
        if (CollectionUtil.isEmpty(records)) {
            return page;
        }
        List<Long> userIdList = records.stream().map(UsersDO::getId).collect(Collectors.toList());

//        Map<Long, List<ProductDTO>> productList = usersProductService.getProductList(userIdList);

        List<UsersDTO> recordList = records.stream().map(it -> {
            UsersDTO users = BeanUtils.transform(UsersDTO.class, it);
//            users.setUsersCatalogList(userCatalogService.getUserCatalogList(it.getCatalogIdList()));
//            users.setUsersLabelList(StringUtil.getList(it.getLabelList()));
//            users.setProductList(productList.get(it.getId()));
            return users;
        }).collect(Collectors.toList());
        page.setRecords(recordList);
        return page;
    }

    @Override
    public Page getRecommendUsers(Page page) {
        Wrapper query = Wrappers.<UsersDO>lambdaQuery();
//                .eq(UsersDO::getType, TypeEnum.DESIGNER.getValue())
//                .gt(UsersDO::getRecommendSort, 0)
//                .orderByDesc(UsersDO::getRecommendSort);
        Page<UsersDO> pageResult = page(page, query);
        List<UsersDO> records = pageResult.getRecords();
        if (CollectionUtil.isEmpty(records)) {
            return page;
        }
        List<Long> userIdList = records.stream().map(UsersDO::getId).collect(Collectors.toList());

//        Map<Long, List<ProductDTO>> productList = usersProductService.getProductList(userIdList);
        List<UsersDTO> recordList = records.stream().map(it -> {
            UsersDTO users = BeanUtils.transform(UsersDTO.class, it);
//            users.setUsersCatalogList(userCatalogService.getUserCatalogList(it.getCatalogIdList()));
//            users.setUsersLabelList(StringUtil.getList(it.getLabelList()));
//            users.setProductList(productList.get(it.getId()));
            return users;
        }).collect(Collectors.toList());
        page.setRecords(recordList);
        return page;
    }

    @Override
    public Page getLatestUsers(Page page) {
        Wrapper query = Wrappers.<UsersDO>lambdaQuery();
//                .eq(UsersDO::getType, TypeEnum.DESIGNER.getValue())
//                .gt(UsersDO::getFreshSort, 0)
//                .orderByDesc(UsersDO::getFreshSort);
        Page<UsersDO> pageResult = page(page, query);


        List<UsersDO> records = pageResult.getRecords();
        if (CollectionUtil.isEmpty(records)) {
            return page;
        }
        List<Long> userIdList = records.stream().map(UsersDO::getId).collect(Collectors.toList());

//        Map<Long, List<ProductDTO>> productList = usersProductService.getProductList(userIdList);

        List<UsersDTO> recordList = records.stream().map(it -> {
            UsersDTO users = BeanUtils.transform(UsersDTO.class, it);
//            users.setUsersCatalogList(userCatalogService.getUserCatalogList(it.getCatalogIdList()));
//            users.setUsersLabelList(StringUtil.getList(it.getLabelList()));
//            users.setProductList(productList.get(it.getId()));
            return users;
        }).collect(Collectors.toList());
        page.setRecords(recordList);
        return page;
    }

    @Override
    public Page<UsersPO> pageList(Page page, UsersPOParam params) {
        Wrapper query = Wrappers.<UsersDO>lambdaQuery()
                .like(StringUtils.isNotBlank(params.getName()), UsersDO::getName, params.getName())
                .like(StringUtils.isNotBlank(params.getPhone()), UsersDO::getPhone, params.getPhone())
                .orderByDesc(UsersDO::getId);
        Page<UsersDO> pageResult = page(page, query);
        List<UsersDO> records = pageResult.getRecords();
        if (CollectionUtil.isEmpty(records)) {
            return page;
        }

        List<Long> userIdList = records.stream().map(UsersDO::getId).collect(Collectors.toList());
        Map<Long, List<LabelValueDTO<String, Long>>> roleListByUserId = getRoleListByUserId(userIdList);

        List<UsersPO> recordList = records.stream().map(it -> {
            UsersPO users = BeanUtils.transform(UsersPO.class, it);
            List<LabelValueDTO<String, Long>> labelValueDTOS = roleListByUserId.get(users.getId());
            users.setRoles(labelValueDTOS);
            users.setLoginPwd(null);
            return users;
        }).collect(Collectors.toList());
        page.setRecords(recordList);
        return page;
    }


    private Map<Long, List<LabelValueDTO<String, Long>>> getRoleListByUserId(List<Long> userIdList) {

        if (CollectionUtil.isEmpty(userIdList)) {
            return new HashMap<>();
        }

        Wrapper query = Wrappers.<UsersRoleDO>lambdaQuery()
                .in(UsersRoleDO::getUsersId, userIdList);

        List<UsersRoleDO> list = usersRoleMapper.selectList(query);


        Map<Long, LabelValueDTO<String, Long>> roleList = getRoleList(list.stream().map(UsersRoleDO::getRoleId).collect(Collectors.toList()));

        HashMap<Long, List<LabelValueDTO<String, Long>>> userIdAndRoleList = list.stream().filter(it -> roleList.get(it.getRoleId()) != null).collect(Collectors.groupingBy(UsersRoleDO::getUsersId, HashMap::new,
                Collectors.mapping(it -> roleList.get(it.getRoleId()), Collectors.toList())));

        return userIdAndRoleList;
    }

    private Map<Long, LabelValueDTO<String, Long>> getRoleList(List<Long> roleIdList) {
        if (CollectionUtil.isEmpty(roleIdList)) {
            return new HashMap<>();
        }

        Wrapper query = Wrappers.<RoleDO>lambdaQuery()
                .in(RoleDO::getId, roleIdList);

        List<RoleDO> list = roleMapper.selectList(query);

        return list.stream().collect(Collectors.toMap(it -> it.getId(), it -> new LabelValueDTO<>(it.getName(), it.getId())));
    }


    @Override
    public UsersPO getUserInfoByPlatform(Long userId) {
        UsersDO usersDO = getById(userId);
        UsersPO usersInfo = BeanUtils.transform(UsersPO.class, usersDO);
//        usersInfo.setUsersCatalogList(userCatalogService.getUserCatalogList(usersDO.getCatalogIdList()));
//        usersInfo.setUsersLabelList(StringUtil.getList(usersDO.getLabelList()));
        return usersInfo;
    }

    @Override
    public Boolean addOrUpdateUserPO(UsersPO usersPO) {
        String phone = usersPO.getPhone();
        if (StringUtils.isBlank(phone)) {
            throw new ApiException(ApiExceptionEnum.ERROR_PARAM);
        }
        UsersDO usersDB = getByPhone(phone);
        //已经存在
        if (usersDB != null && usersPO.getId() == null) {
            throw new ApiException(ApiExceptionEnum.MOBILE_ERROR);
        } else if (usersDB != null && !Objects.equals(usersDB.getId(), usersPO.getId())) {
            throw new ApiException(ApiExceptionEnum.MOBILE_ERROR);
        }
        UsersDO transform = BeanUtils.transform(UsersDO.class, usersPO);
        if (transform.getId() != null) {
            transform.setLoginPwd(null);
        }
        saveOrUpdate(transform);

        usersRoleMapper.delete(
                Wrappers.<UsersRoleDO>lambdaQuery().eq(UsersRoleDO::getUsersId, transform.getId())
        );


        Optional.ofNullable(usersPO.getRoles()).orElse(Lists.newArrayList()).stream().forEach((it) -> {
            UsersRoleDO usersRoleDO = new UsersRoleDO();
            usersRoleDO.setUsersId(transform.getId());
            usersRoleDO.setRoleId(it.getValue());
            usersRoleMapper.insert(usersRoleDO);
        });
        if (CollectionUtil.isNotEmpty(usersPO.getRoles())) {
            usersPO.getRoles().forEach(it -> {
                RoleDO roleDO = roleMapper.selectById(it.getValue());
                Integer count = usersRoleMapper.selectCount(
                        Wrappers.lambdaQuery(UsersRoleDO.class)
                                .eq(UsersRoleDO::getRoleId, roleDO.getId())
                );
                roleDO.setUserCount(count);
                roleMapper.updateById(roleDO);
            });
        }

        return true;
    }

    @Override
    public Boolean changePassword(PasswordParam usersPO) {
        UsersDO usersDO = getById(usersPO.getUserId());
        usersDO.setLoginPwd(usersPO.getPassword());
        return updateById(usersDO);
    }

    @Override
    public List<LabelValueDTO> getEmployerList() {
        return list(Wrappers.<UsersDO>lambdaQuery()
//                .eq(UsersDO::getType, TypeEnum.HIRE.getValue())
//                .isNotNull(UsersDO::getIcon)
//                .isNotNull(UsersDO::getNickName)
        ).stream().map(it -> {
            LabelValueDTO<String, Long> label = new LabelValueDTO<>();
//            label.setLabel(it.getNickName());
            label.setValue(it.getId());
            return label;
        }).collect(Collectors.toList());
    }

    @Override
    public List<LabelValueDTO> getEmployeeList() {
        return list(Wrappers.<UsersDO>lambdaQuery()
//                .eq(UsersDO::getType, TypeEnum.DESIGNER.getValue())
//                .isNotNull(UsersDO::getIcon)
//                .isNotNull(UsersDO::getNickName)
        ).stream().map(it -> {
            LabelValueDTO<String, Long> label = new LabelValueDTO<>();
//            label.setLabel(it.getNickName());
            label.setValue(it.getId());
            return label;
        }).collect(Collectors.toList());
    }

    @Override
    public Boolean disableUser(UsersPO users) {
        UsersDO byId = getById(users.getId());
        byId.setStatus(users.getStatus());
        return updateById(byId);
    }


    UsersDO getByPhone(String phone) {
        return getOne(Wrappers.<UsersDO>lambdaQuery().eq(UsersDO::getPhone, phone));
    }

}
